package org.mfw.ddm.amp.mdm
{
	import flash.events.EventDispatcher;
	import flash.media.Sound;
	import flash.net.URLRequest;
	
	import org.mfw.ddm.amp.mdc.AMPMediaConnectionManager;
	import org.mfw.ddm.amp.mdc.core.AMPFunctions;
	import org.mfw.ddm.amp.mdc.event.AMPEvent;
	import org.mfw.interfaces.mdm.IMediaDataManager;
	import org.mfw.interfaces.obj.mob.IAlbum;
	import org.mfw.obj.DataManagerServerInfo;
	import org.mfw.obj.events.BoxEvent;
	import org.mfw.obj.events.CoverEvent;
	import org.mfw.obj.events.DataManagerErrorEvent;
	import org.mfw.obj.events.DataManagerInfoEvent;
	import org.mfw.obj.events.MediaStreamEvent;
	import org.mfw.obj.list.AlbumList;
	import org.mfw.obj.list.BoxList;
	import org.mfw.obj.list.GenreList;
	import org.mfw.obj.list.SongList;
	import org.mfw.obj.mob.Album;
	import org.mfw.obj.mob.Box;
	import org.mfw.obj.mob.Cover;
	import org.mfw.obj.mob.Genre;
	import org.mfw.obj.mob.Song;

	/**
	 * The MediaDataManger parse all AmpResults in MediaObjects. This class
	 * caches your Mediadata and save's all Mediahandles. 
	 * 
	 * */
	public class AMPMediaDataManager extends EventDispatcher implements IMediaDataManager
	{
		private var _ampConnection:AMPMediaConnectionManager; // AmpacheConnector
		private var _blankAlbumURL:String = "/images/blankalbum.gif"; // Picturer for blank Cover
		private var _blankCover:Cover; // Cover for Blankcover
		private var _serverInfo:DataManagerServerInfo; // Ampacheserverinfo
		private var _genreList:Array = new Array(); // Cache for Genre
		private var _albumList:Array = new Array(); // Cache for album
		private var _songList:Array = new Array(); // Cache for songs
		public function AMPMediaDataManager()
		{
		}

		/**
		 * Set the initial Parameter of Datamanager.
		 * Here: Key, url, destination of the AmpacheServer
		 * */
		
		public function setParams(params:Object):Boolean
		{
			if ((params.hasOwnProperty("key"))&& (params.hasOwnProperty("url"))&&(params.hasOwnProperty("destination")))
			{
				this._ampConnection= new AMPMediaConnectionManager(params.key,params.url,params.destination);
				this._ampConnection.addEventListener(AMPEvent.AMP_GENRES,handleGenresResult);
				this._ampConnection.addEventListener(AMPEvent.AMP_GENRE_ALBUMS,handleGenreAlbumsResult);
				this._ampConnection.addEventListener(AMPEvent.AMP_ALBUM_SONGS,handleAlbumSongsResult);
				this._ampConnection.addEventListener(AMPEvent.AMP_HANDSHAKE,handleHandshakeResult);
				this._ampConnection.addEventListener(AMPEvent.AMP_ERROR, handleServerError);
				this._ampConnection.connect();
				this._blankCover=new Cover(0,params.url+this._blankAlbumURL);
				
				return true;
			}
			else return false;
		}
		
		
		
		
		/**
		 * Try to get the first Box (rootBox)
		 * */
		public function getStartBox():Boolean
		{
			this.getBoxByID(0);
			return true;	
		}
		
		/**
		 * Order a Box by ID. 
		 * */
		public function getBoxByID(ID:Number):Boolean
		{
			var dbID:Number = this.extractDataBaseIDfromID(ID);
			switch (this.extractTypeFromID(ID)){
			//Rootbox
			case 0:	this._ampConnection.addRequest(AMPFunctions.AMP_GENRES);
					break;
			//Genrebox
			case 1: this._ampConnection.addRequest(AMPFunctions.AMP_GENRE_ALBUMS,dbID.toString());
					break;
			//Albumbox
			case 2: this._ampConnection.addRequest(AMPFunctions.AMP_ALBUM_SONGS,dbID.toString());
					break;
			default: return false;
			}
			return true;
		}
		
		/**
		 * Order a Cover by ID
		 * */
		public function getCoverByID(ID:Number):Boolean{
			var dbID:Number = this.extractDataBaseIDfromID(ID);
			switch (this.extractTypeFromID(ID)){
			//Rootcover
			case 0:	super.dispatchEvent(new CoverEvent(CoverEvent.COVER_RECEIVED, this._blankCover));
					break;
			//Genrecover
			case 1: super.dispatchEvent(new CoverEvent(CoverEvent.COVER_RECEIVED, this._blankCover));
					break;
			//Albumcover
			case 2: var tempAlbum:Album = this._albumList[dbID];
					super.dispatchEvent(new CoverEvent(CoverEvent.COVER_RECEIVED,tempAlbum.cover));
					break;
			default: return false;
			}
			return true;
		}
		
		/**
		 * Order a SongStream by ID
		 * */
		public function getSongStreamByID(ID:Number):Boolean{
			var song:Song = this._songList[ID] as Song;
			var sound:Sound = new Sound();
			var urlRequest:URLRequest = new URLRequest(song.songURL);
			sound.load(urlRequest);
			super.dispatchEvent(new MediaStreamEvent(MediaStreamEvent.SOUND_RECEIVE,sound));
			return true;
		}
	

//----------------------------Boxbuilder--------------------------------
		/**
		 * Builds a Box from GenreList
		 * */
		protected function buildGenreBox(genreList:GenreList):void{
			var startBox:Box = new Box(0,this._blankCover); //Generiert eine neue Box
			var startBoxList:BoxList = new BoxList(); //Neue Boxlist welche Daten der Unterbox enthält (nur ID und Name)
			for each (var value:Genre in genreList.elementArray) { // Durchlaufe alle Elemente im Elementarray der Genrelist
				var boxID:Number = Number(String(value.ID)+".1"); //Generiere eine neue ID für die BOX (genreID + .1)
				var genreBox:Box = new Box(boxID,this._blankCover); //Erstelle eine neue Box mit der generierten ID und dem leeren Cover
				genreBox.name=value.name; //Gib der Box einen Namen (Name des Genres)
				startBoxList.addElement(genreBox); //Füge der startBoxList diese Box hinzu				 
			}
			startBox.boxList=startBoxList; //nehme die Startbox und weiße ihr die startBoxList zu
			super.dispatchEvent(new BoxEvent(BoxEvent.COMPLETE,startBox)); // wirf ein BoxEvent
		}
		
		
		/**
		 * Builds a Box from AlbumList
		 * */
		protected function buildAlbumsBox(albumsList:AlbumList):void{
			var albumsBox:Box = new Box(albumsList.currentAlbum.genre.ID+.1,this._blankCover); //Erstelle eine neue Box (Wird AlbumBox)
			//Durchlaufe alle Alben in der AlbumsList und erzeuge für jedes Album eine Box
			do { 	
					var boxID:Number = Number(String(albumsList.currentAlbum.ID)+".2"); //Erzeuge eine neue ID für die BOX (albumID +.2)
					var boxInside:Box = new Box(boxID,albumsList.currentAlbum.cover); // Erzeuge eine neue Box (bekommt Cover des Albums und die eben erzeugte ID) 
					boxInside.name = albumsList.currentAlbum.name; //Gib der Box den Namen des Albums
					albumsBox.boxList.addElement(boxInside); // Füge der Box welche die Alben enthält die eben erzeugte Box hinzu (in die BoxList)
	//--optional----------------------------------------------------------------------			
					this._albumList[albumsList.currentAlbum.ID]=albumsList.currentAlbum; //Speichere diese Box in den Cache des Datenmanagers 
    			}
			while (albumsList.nextAlbum) //Switche zum nächsten Album in der AlbumsList, Rückgabewert ist null wenn es keine neues Album gibt
			super.dispatchEvent(new BoxEvent(BoxEvent.COMPLETE,albumsBox)); // Wirf das Boxevent
		}
		
		
		 	
		protected function buildBox(albumsList:AlbumList):void{
			var albumsBox:Box = new Box(albumsList.currentAlbum.genre.ID+.1,this._blankCover); //Erstelle eine neue Box (Wird AlbumBox)
			//Durchlaufe alle Alben in der AlbumsList und erzeuge für jedes Album eine Box
			do { 	
					var boxID:Number = Number(String(albumsList.currentAlbum.ID)+".2"); //Erzeuge eine neue ID für die BOX (albumID +.2)
					var boxInside:Box = new Box(boxID,albumsList.currentAlbum.cover); // Erzeuge eine neue Box (bekommt Cover des Albums und die eben erzeugte ID) 
					boxInside.name = albumsList.currentAlbum.name; //Gib der Box den Namen des Albums
					albumsBox.boxList.addElement(boxInside); // Füge der Box welche die Alben enthält die eben erzeugte Box hinzu (in die BoxList)
	//--optional----------------------------------------------------------------------			
					this._albumList[albumsList.currentAlbum.ID]=albumsList.currentAlbum; //Speichere diese Box in den Cache des Datenmanagers 
    			}
			while (albumsList.nextAlbum) //Switche zum nächsten Album in der AlbumsList, Rückgabewert ist null wenn es keine neues Album gibt
			super.dispatchEvent(new BoxEvent(BoxEvent.COMPLETE,albumsBox)); // Wirf das Boxevent
		}
		
		/**
		 * Builds a Box from SongList
		 * */
		protected function buildSongBox(songList:SongList):void{
			var tempAlbum:IAlbum=songList.currentSong.album;
			var albumsBox:Box = new Box(tempAlbum.ID+.2,tempAlbum.cover);
			albumsBox.songs=songList;
			super.dispatchEvent(new BoxEvent(BoxEvent.COMPLETE,albumsBox));
			songList.currentIndex=0;
			while (songList.nextElement) {
				this._songList[songList.currentSong.ID]=songList.currentSong;
			}
		}
//----------------------------IDFunctions--------------------------------
		/**
		 * Extrace the Type from the ID
		 * */
		protected function extractTypeFromID(ID:Number):Number {
			return Number(ID.toString().substr(ID.toString().length-1,1));
		}
		
		/**
		 * Extrace the DatabaseID from ID
		 * */
		protected function extractDataBaseIDfromID(ID:Number):Number {
			return Number(ID.toString().substr(0,ID.toString().length-2));
		}
		
		
//----------------------------ServerResulthandler--------------------------------		
		protected function handleServerError(e:AMPEvent):void {
			super.dispatchEvent(new DataManagerErrorEvent(DataManagerErrorEvent.ERROR_RECEIVE,e.object.root.error));
		}
		
		protected function handleHandshakeResult(e:AMPEvent):void{
			this._serverInfo= new DataManagerServerInfo(e.object.root);
			super.dispatchEvent(new DataManagerInfoEvent(DataManagerInfoEvent.SERVER_INFO_RECEIVE,this._serverInfo));
		
		}
		
		protected function handleGenresResult(e:AMPEvent):void{
			this.buildGenreBox(new GenreList(e.object.root.genre));
		}
				
	
		protected function handleAlbumSongsResult(e:AMPEvent):void{
			this.buildSongBox(new SongList(e.object.root.song));
		}
		
		protected function handleGenreAlbumsResult(e:AMPEvent):void{
			this.buildAlbumsBox(new AlbumList(e.object.root.album));
		}
	
		public function get debugText():String
		{
			return null;
		}
	}
}